package com.ruicar.afs.cloud.afscase.processor.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruicar.afs.cloud.afscase.approvetask.entity.CaseApproveRecord;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkProcessScheduleInfo;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkProcessScheduleInfoTemp;
import com.ruicar.afs.cloud.afscase.approvetask.entity.WorkTaskPool;
import com.ruicar.afs.cloud.afscase.approvetask.service.CaseApproveRecordService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkProcessScheduleInfoService;
import com.ruicar.afs.cloud.afscase.approvetask.service.WorkTaskPoolService;
import com.ruicar.afs.cloud.afscase.common.utils.Const;
import com.ruicar.afs.cloud.afscase.infomanagement.entity.CaseCustInfo;
import com.ruicar.afs.cloud.afscase.infomanagement.service.CaseCustInfoService;
import com.ruicar.afs.cloud.afscase.mq.approvesendinfo.service.ApproveInformInfoService;
import com.ruicar.afs.cloud.afscase.processor.enums.NormalSubmitType;
import com.ruicar.afs.cloud.afscase.processor.service.ChangeAssetsWorkflowService;
import com.ruicar.afs.cloud.afscase.processor.service.ReconsiderationWorkflowService;
import com.ruicar.afs.cloud.afscase.processor.util.WorkflowTypeUtil;
import com.ruicar.afs.cloud.afscase.processor.vo.NormalTaskSubmitVO;
import com.ruicar.afs.cloud.afscase.reconsiderationprocess.entity.ApproveReconsiderationInfo;
import com.ruicar.afs.cloud.afscase.reconsiderationprocess.service.ReconsiderationProcessService;
import com.ruicar.afs.cloud.common.core.enums.AfsEnumUtil;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.modules.afscorebusiness.enums.*;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.WorkFlowResponse;
import com.ruicar.afs.cloud.workflow.api.dto.flowprocess.request.StartFlowRequest;
import com.ruicar.afs.cloud.workflow.gwt.service.WorkflowService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
@AllArgsConstructor
public class ReconsiderationWorkflowServiceImpl implements ReconsiderationWorkflowService {
    private WorkflowService workflowService;
    private CaseApproveRecordService caseApproveRecordService;
    private ApproveInformInfoService approveInformInfoService;
    private CaseCustInfoService custInfoService;
    private ReconsiderationProcessService reconsiderationProcessService;
    private WorkTaskPoolService workTaskPoolService;
    private WorkProcessScheduleInfoService workProcessScheduleInfoService;
    private ChangeAssetsWorkflowService assetsWorkflowService;

    /**
     * @description: 复议流程发起
     * @author xiaolongsubmitApprove
     * @version 1.0
     */
    public WorkFlowResponse startReconsideration(WorkProcessScheduleInfoTemp temp,String reconReason) {
        StartFlowRequest request = new StartFlowRequest();
        request.setAfsFlowKey(temp.getAfsFlowKey());
        request.setBizDataId(Convert.toStr(temp.getId()));
        request.setFlowName(new StringBuffer(temp.getApplyNo())
                .append("-")
                .append(WorkflowTypeUtil.getApproveTypeName(temp.getAfsFlowKey()))
                .append("(")
                .append(WorkflowTypeUtil.getType(temp.getAfsFlowKey()).getDesc())
                .append(")").toString());
        log.info("复议流程发起 ==> {}", request);
        WorkFlowResponse response = workflowService.startWorkFlow(request, assetsWorkflowService.getBusinessData(temp.getApplyNo()));
        if (Const.WORKFLOW_RESPONSE_SUCCESS == response.getSuccess()) {
            saveStartRecord(temp,reconReason);
        } else {
            throw new AfsBaseException(response.getCode(), response.getMessage());
        }
        return response;
    }

    /**
     * @description:保存流程发起日志
     * @author xiaolong
     * @version 1.0
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveStartRecord(WorkProcessScheduleInfoTemp infoTemp,String reconReason) {
        CaseApproveRecord record = new CaseApproveRecord();
        record.setStageId(Convert.toStr(infoTemp.getId()));
        record.setApplyNo(infoTemp.getApplyNo());
        record.setApproveSuggestName("复议申请发起流程");
        record.setDisposeNodeName("开始节点");
        record.setDisposeStaff("系统");
        record.setApproveType(ApproveTypeEnum.PROCESS.getValue());
        record.setApproveStartTime(infoTemp.getStartTime());
        record.setApproveEndTime(new Date());
        caseApproveRecordService.save(record);

        //复议申请表
        saveApproveReconsiderationInfo(infoTemp,reconReason);

        // 通知进件端
        CaseApproveRecord noticeRecord = new CaseApproveRecord();
        noticeRecord.setApplyNo(record.getApplyNo());
        noticeRecord.setApproveStartTime(new Date());
        noticeRecord.setApproveSuggest(SendApproveTypeEnum.PENDING_REVIEW.getCode());
        approveInformInfoService.approveReconsideration(noticeRecord);
    }

    /**
     * @description: 复议申请表
     * @author xiaolong
     * @version 1.0
     */
    private void saveApproveReconsiderationInfo(WorkProcessScheduleInfoTemp temp,String reconReason) {
        ApproveReconsiderationInfo reconsiderationInfo = new ApproveReconsiderationInfo();

        reconsiderationInfo.setStageId(Convert.toStr(temp.getId()));
        reconsiderationInfo.setReconReason(reconReason);
        reconsiderationInfo.setApplyNo(temp.getApplyNo());
        reconsiderationInfo.setStatus(AfsEnumUtil.key(BusinessStateInEnum.WAIT_CHECK));
        CaseCustInfo caseCustInfo = custInfoService.getOne(Wrappers.<CaseCustInfo>query().lambda()
                .eq(CaseCustInfo::getApplyNo, temp.getApplyNo())
                .eq(CaseCustInfo::getCustRole, AfsEnumUtil.key(CustRoleEnum.MIANCUST)));
        reconsiderationInfo.setCustId(caseCustInfo.getId());
        reconsiderationProcessService.save(reconsiderationInfo);
    }
    /**
     * @description: 复议流程提交
     * @author jiaqi.guo
     * @created 2020/7/27 19:19
     * @version 1.0
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(NormalTaskSubmitVO submitVO) {
        if (Objects.isNull(submitVO.getWorkFlowInfo())) {
            WorkProcessScheduleInfo workProcessScheduleInfo=workProcessScheduleInfoService.getById(submitVO.getRecord().getStageId());
            if(ObjectUtils.isNotEmpty(workProcessScheduleInfo)){
                workProcessScheduleInfo.setFirstTrail(WhetherEnum.NO.getCode());
            }
            submitVO.setWorkFlowInfo(workProcessScheduleInfo);
        }
        if (Objects.isNull(submitVO.getWorkTaskPool())) {
            submitVO.setWorkTaskPool(workTaskPoolService.getOne(
                    Wrappers.<WorkTaskPool>lambdaQuery()
                            .eq(WorkTaskPool::getStageId, submitVO.getWorkFlowInfo().getId().toString())
                            .eq(WorkTaskPool::getTaskNodeId, submitVO.getWorkFlowInfo().getCurrentNodeId())
                            .eq(WorkTaskPool::getApproveStaff, SecurityUtils.getUser().getUsername())
            ));
        }
        NormalSubmitType submitEnum = (NormalSubmitType) AfsEnumUtil.getEnum(submitVO.getRecord().getApproveSuggest(), NormalSubmitType.class);
        switch (submitEnum) {
            case SUGGEST_CHECK:
                assetsWorkflowService.check(submitVO);
                break;
            case SUGGEST_REJECT:
                assetsWorkflowService.reject(submitVO);
                break;
            case SUGGEST_REJECT_FINAL:
                assetsWorkflowService.checkApproveAmountLimit(submitVO.getWorkFlowInfo().getApplyNo());
                assetsWorkflowService.rejectFinal(submitVO);
                break;
            case SUGGEST_CHECK_FINAL:
                assetsWorkflowService.checkApproveAmountLimit(submitVO.getWorkFlowInfo().getApplyNo());
                assetsWorkflowService.checkFinal(submitVO);
                break;
            case SEND_BACK:
                assetsWorkflowService.sendBack(submitVO);
                break;
            case SEND_BACK_TO_DEALER:
                assetsWorkflowService. sendBackToDealer(submitVO);
                break;
            default:
                log.info("审批建议不存在:{}", submitEnum);
        }
    }

}
